package Buildings.dwelling;
import Interfaces.*;
import java.util.Iterator;
public class Dwelling implements Building, java.io.Serializable,Cloneable{
    private Floor DwellingFloors[];
    //Внутренний класс Итератора
    private class myIterator implements Iterator{
        private int index=-1;
        public boolean hasNext(){
            return ((boolean)(index+1<DwellingFloors.length));
        }
        public Floor next(){
            if(index<DwellingFloors.length){
            index++;
            return DwellingFloors[index];
            }else return null;
        }
        public void remove(){
            throw new UnsupportedOperationException();
        }    
    }
    
    @Override
    public java.util.Iterator iterator(){
        return new myIterator();
    }
    @Override
    public int getHowMuchFloorInBuilding(){
        return DwellingFloors.length;
    }
    @Override
    public int getHowMuchSpaceInBuilding(){
        int k=0;
        for(int i=0;i<DwellingFloors.length;i++){
            k+=DwellingFloors[i].getHowMuchSpaceInFloor();
        }
        return k;
    }
    @Override
    public double getHowMuchAreaInBuilding(){
        int s=0;
        for(int i=0;i<DwellingFloors.length;i++){
            s+=DwellingFloors[i].getHowMuchAreaInFloor();
        }
        return s;
    }
    @Override
    public int getHowMuchRoomsInBuilding(){
        int m=0;
        for(int i=0;i<DwellingFloors.length;i++){
            m+=DwellingFloors[i].getHowMuchRoomsInFloor();
        }
        return m;
    }
    @Override
    public Floor[] getFloorMass(){//отдаем ссылку на массив этажей
        return DwellingFloors;
    }
    @Override
    public Floor getFloor(int i){
        if(i>=0 && i<DwellingFloors.length){
            return DwellingFloors[i];
        }else{
            System.out.println("Такого этажа не существует!");
            return null;
        }
    }
    @Override
    public void setFloor(int i, Floor floor){
        if(i>=0 && i<DwellingFloors.length){
            DwellingFloors[i]=(Floor)floor.clone();
        }else System.out.println("Этажа с таким номером не существует!");
    }
    @Override
    public Space getSpaceInBuilding(int i){
        Space m=null;
        if(i>=0 && i<getHowMuchSpaceInBuilding()){
            for(int j=0;j<DwellingFloors.length;j++){
                if(i<DwellingFloors[j].getHowMuchSpaceInFloor()){//номер на этом этаже
                    m=DwellingFloors[j].getSpaceInFloor(i);
                    return m;
                }
                if(i>=DwellingFloors[j].getHowMuchSpaceInFloor()){//если номер больше чем есть на этаже
                    i-=DwellingFloors[j].getHowMuchSpaceInFloor();
                }
            }
        }
        return m;
    }
    @Override
    public void setSpaceInBuilding(int i,Space s){
        if(i>=0 && i<getHowMuchSpaceInBuilding()){
            for(int j=0;j<DwellingFloors.length;j++){
                if(i<DwellingFloors[j].getHowMuchSpaceInFloor()){//номер на этом этаже
                    DwellingFloors[j].setSpaceInFloor(i,s);
                    return;
                }
                if(i>=DwellingFloors[j].getHowMuchSpaceInFloor()){//если номер больше чем есть на этаже
                    i-=DwellingFloors[j].getHowMuchSpaceInFloor();
                }
            }
        }
    }
    @Override
    public void addSpaceInBuilding(int i,Space s){
        int n=0;
        for(int j=0;j<DwellingFloors.length;j++)
            n+=DwellingFloors[j].getMassSpacesInFloor().length;
        if(i>=0 &&i<n){
            for(int j=0;j<DwellingFloors.length;j++)
            {
                if(i<DwellingFloors[j].getMassSpacesInFloor().length){
                    DwellingFloors[j].addSpaceInFloor(i,s);
                    return;
                }
                if(i>=DwellingFloors[j].getMassSpacesInFloor().length){
                    i-=DwellingFloors[j].getMassSpacesInFloor().length;
                }
            }
        }
    }
    @Override
    public void delSpaceInBuilding(int i){
         if(i>=0 && i<=getHowMuchSpaceInBuilding()){
            for(int j=0;j<DwellingFloors.length;j++){
                if(i<DwellingFloors[j].getHowMuchSpaceInFloor()){//номер на этом этаже
                    DwellingFloors[j].delSpaceInFloor(i);
                    return;
                }
                if(i>=DwellingFloors[j].getHowMuchSpaceInFloor()){//если номер больше чем есть на этаже
                    i-=DwellingFloors[j].getHowMuchSpaceInFloor();
                }
            }
        }
    }
    @Override
    public Space getBestSpace(){
        Space best=DwellingFloors[0].getBestSpace();
        for(int i=1;i<DwellingFloors.length;i++){
            if(best.getHowMuchArea()<DwellingFloors[i].getBestSpace().getHowMuchArea()){
                best=DwellingFloors[i].getBestSpace();
            }
        }
        return best;
    }
    @Override
    public Space[] getSorted(){
        int n=getHowMuchSpaceInBuilding();
        Space s[] = new Space[n];
        int h=0;
        for(int i=0;i<DwellingFloors.length;i++){
            Space m[]=DwellingFloors[i].getMassSpacesInFloor();//создаем этаж для обработки
            for(int j=0;j<m.length;j++){
                    s[h]=m[j];
                    h++;
            }
        }
        //заполнили всеми квартирами
        //сортировка шелла
        int shag;
        Space buf;
        shag=(int)n/2;
        while(shag>0){
            for(int i=0;i<(n-shag);i++){
                if(s[i].getHowMuchArea()<s[i+shag].getHowMuchArea()){
                    buf=s[i];
                    s[i]=s[i+shag];
                    s[i+shag]=buf;   
                }
            }
            shag--;
        }
        return s;
    }
    @Override
    
    public String toString(){
        StringBuilder s=new StringBuilder();
        s.append(("Жилое здание \n"));
        for(int i=0;i<getHowMuchFloorInBuilding();i++){
            s.append((i+getFloor(i).toString()));
        }
        return s.toString();
    }
    public boolean equals(Object o){
        boolean answer=false;
        if(o.getClass()==this.getClass()){
            if(((Dwelling)o).getHowMuchFloorInBuilding()==this.getHowMuchFloorInBuilding()){
                boolean key=true;
                for(int i=0;i<getHowMuchFloorInBuilding();i++){
                    if(this.getFloor(i).equals(((Dwelling)o).getFloor(i))==false){
                        key=false;
                        break;
                    }
                }
                if(key==true)answer=true;
            }
        }
        return answer;
    }
    public int hashCode(){
        int hash;
        hash=(int)(Integer.bitCount(this.getHowMuchFloorInBuilding()));
        for(int i=0;i<this.getHowMuchFloorInBuilding();i++){
            hash=(int)(hash ^ this.getFloor(i).hashCode());
        }
        return hash;
    }
    public Object clone(){
        Floor[] forClone=new Floor[getHowMuchFloorInBuilding()];
        for(int i=0;i<getHowMuchFloorInBuilding();i++){
            forClone[i]=(Floor)DwellingFloors[i].clone();
        }
        return new Dwelling(forClone);
    }       
    //конструкторы
    public Dwelling(int howMuchFloor, int ...flatsInFloor){
        if(howMuchFloor==flatsInFloor.length){
            DwellingFloors=new Floor[howMuchFloor];
            for(int i=0;i<howMuchFloor;i++){
                DwellingFloors[i]=new DwellingFloor(flatsInFloor[i]);
            }
        }else System.out.println("Не возможно создать объект здание!");
    }
    public Dwelling(Floor ... enotherMassOfFloor){//создаем дом на данных этажах
        int n=enotherMassOfFloor.length;
        DwellingFloors=new Floor[n];
        for(int i=0;i<n;i++){
            DwellingFloors[i]=enotherMassOfFloor[i];
        }  
    }
}